﻿namespace Glue.Internals
{
    internal class Mapper<LeftType, RightType>
    {
        private readonly RelationContainer<LeftType, RightType> relations;

        public Mapper(RelationContainer<LeftType, RightType> mapping)
        {
            relations = mapping;
        }

        public RightType Map(LeftType from, RightType to)
        {
            foreach (var relation in relations.GetRelationsTowardsRight())
            {
                if (relation.CanMapFromThisLeftSideObject(from)) 
                {
                    var outValue = relation.RightMember.InvokeGet(to);
                    var value = relation.GetConverter().Map(relation.LeftMember.InvokeGet(from), outValue);
                    relation.RightMember.InvokeSet(to,value);
                }
            }
            return to;
        }

        public LeftType Map(RightType from, LeftType to)
        {
            foreach (var relation in relations.GetRelationsTowardsLeft())
            {
                if (relation.CanMapFromThisRightSideObject(from)) 
                {
                    var outValue = relation.LeftMember.InvokeGet(to);
                    var value = relation.GetConverter().Map(relation.RightMember.InvokeGet(from), outValue);
                    relation.LeftMember.InvokeSet(to, value);
                }
            }
            return to;
        }
    }
}